package org.jrfe.scene.impl;

import org.jrfe.math.Transform2D;
import org.jrfe.math.Vector2f;
import org.jrfe.math.bound.Bound;
import org.jrfe.math.bound.BoundRect;
import org.jrfe.scene.Entity;
import org.jrfe.util.FastMath;


public class Leaf extends BaseNode implements Comparable<Leaf>{

	protected Entity entity;
	protected int z;
	protected int mask;
	protected UserData userData;
	
	public Leaf(Entity entiry) {
		this.entity = entiry;
		setBound(new BoundRect(new Vector2f(),entiry.getWidth() /2,entiry.getHeight()/2));
	}
	
	public Entity getEntity() {
		return entity;
	}
	
	public void setEntity(Entity entity) {
		this.entity = entity;
		getBound().updateSize(entity.getWidth() / 2,entity.getHeight() / 2);
		
	}
	
	@Override
	public void transform(Transform2D t) {
		worldTransform.add(t);
		/*if(getParent() != null){
			localTransform.setRotate(worldTransform.getRotate() - getParent().getWorldTransform().getRotate()); 
		}else{
			localTransform.setTo(worldTransform);
		}*/
		applayTransform();
	}
	
	@Override
	public void translate(Vector2f v) {
		worldCenter.add(v);
		if(getParent() != null){
			localCenter.set(worldCenter.x - getParent().getWorldCenter().x, worldCenter.y - getParent().getWorldCenter().y);
		}else{
			localCenter.set(worldCenter);
		}
		
		applayTranslate();
	}
	
	@Override
	public void applayTransform() {
	
		float rcos = FastMath.abs(getWorldTransform().getCosAngle());
		float rsin = FastMath.abs(getWorldTransform().getSinAngle());
		
		float h = entity.getHeight()*rcos + entity.getWidth()*rsin;
		float w = entity.getHeight()*rsin + entity.getWidth()*rcos;
		
		getBound().xExtent = w / 2;
		getBound().yExtent = h / 2;
	}
	
	@Override
	public void applayTranslate() {
		getBound().center.set(worldCenter);		
	}

	
	@Override
	public void updateBound() {
		
		if(getParent() != null){
			super.updateBound();
		}
	}
	
	@Override
	public int compareTo(Leaf o) {
		
		if (z > o.z) {
			return 1;
		} else if (z < o.z) {
			return -1;
		} else {
			Bound bb = getBound();
			Bound ob = o.getBound();
			float h = bb.center.y + bb.yExtent;
			float h1 = ob.center.y + ob.yExtent;;
			if (h > h1) {
				return 1;
			} else if (h < h1) {
				return -1;
			} else {
				
				float x  = bb.center.x - bb.xExtent;
				float x1 = ob.center.x - ob.xExtent;
				
				if (x > x1) {
					return 1;
				} else if (x < x1) {
					return -1;
				} else {
					return 1;
				}
			}
		}
	}

	public int getZ() {
		return z;
	}

	public void setZ(int z) {
		this.z = z;
	}

	public int getMask() {
		return mask;
	}

	public void setMask(int mask) {
		this.mask = mask;
	}
	
	public UserData getUserData() {
		return userData;
	}
	
	public void setUserData(UserData userData) {
		this.userData = userData;
	}
	
	
}
